﻿using PPIDesktopClient.General;
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using VMind.Global;

namespace PPIDesktopClient
{
    public partial class Validator : Label
    {
        public Validator()
        {
            this.BackColor = System.Drawing.Color.Transparent;
            this.Visible = false;
        }
        #region Private Members
        private Control m_ControlToValidate = null;
        private bool m_IsValid = true;
        private bool m_RequiredFieldValidator = false;
        private string m_InitialValue = "";
        private string m_RequiredFieldErrorMessage = "";
        private bool m_CompareValidator = false;
        private string m_CompareErrorMessage = "";
        private ValidationDataTypes m_DataType = ValidationDataTypes.String;
        private ValidationOperators m_Operator = ValidationOperators.None;
        private string m_ValueToCompare = "";
        private Control m_ControlToCompare = null;
        private bool m_RegularExpressionValidator = false;
        private string m_RegularExpressionErrorMessage = "";
        private string m_RegularExpression = "";
        #endregion
        #region Public Properties
        public bool IsValid
        {
            get { return m_IsValid; }
            set { m_IsValid = value; }
        }
        public Control ControlToValidate
        {
            get { return m_ControlToValidate; }
            set { m_ControlToValidate = value; }
        }
        /// <summary>
        /// Whether or not this should check if the control has data entered
        /// </summary>
        public bool RequiredFieldValidator
        {
            get { return m_RequiredFieldValidator; }
            set { m_RequiredFieldValidator = value; }
        }
        public string RequiredFieldErrorMessage
        {
            get { return m_RequiredFieldErrorMessage; }
            set { m_RequiredFieldErrorMessage = value; }
        }
        public string InitialValue
        {
            get { return m_InitialValue; }
            set { m_InitialValue = value; }
        }
        /// <summary>
        /// Whether or not this should compare the control with a specified value or another control
        /// </summary>
        public bool CompareValidator
        {
            get { return m_CompareValidator; }
            set { m_CompareValidator = value; }
        }
        public string CompareErrorMessage
        {
            get { return m_CompareErrorMessage; }
            set { m_CompareErrorMessage = value; }
        }
        public ValidationDataTypes DataType
        {
            get { return m_DataType; }
            set
            {
                if (!String.IsNullOrEmpty(m_ValueToCompare))
                {
                    switch (value)
                    {
                        case ValidationDataTypes.Integer:
                            if (ConvertHelper.ToInt32(m_ValueToCompare) == Int32.MinValue)
                                m_ValueToCompare = "";
                            break;
                        case ValidationDataTypes.Double:
                            if (ConvertHelper.Todouble(m_ValueToCompare) == double.MinValue)
                                m_ValueToCompare = "";
                            break;
                    }
                }
                m_DataType = value;
                if (m_DataType == ValidationDataTypes.String)
                    m_Operator = ValidationOperators.Equal;
            }
        }
        public ValidationOperators Operator
        {
            get { return m_Operator; }
            set { m_Operator = value; }
        }
        public string ValueToCompare
        {
            get { return m_ValueToCompare; }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    switch (m_DataType)
                    {
                        case ValidationDataTypes.Integer:
                            if (ConvertHelper.ToInt32(value) == Int32.MinValue)
                                throw new Exception("Value is invalid for selected data type");
                            break;
                        case ValidationDataTypes.Double:
                            if (ConvertHelper.Todouble(value) == double.MinValue)
                                throw new Exception("Value is invalid for selected data type");
                            break;
                    }
                }
                m_ControlToCompare = null;
                m_ValueToCompare = value;
            }
        }
        public Control ControlToCompare
        {
            get { return m_ControlToCompare; }
            set
            {
                m_ValueToCompare = "";
                m_ControlToCompare = value;
            }
        }
        /// <summary>
        /// Whether or not this should validate the control with a regular expression
        /// </summary>
        public bool RegularExpressionValidator
        {
            get { return m_RegularExpressionValidator; }
            set { m_RegularExpressionValidator = value; }
        }
        public string RegularExpressionErrorMessage
        {
            get { return m_RegularExpressionErrorMessage; }
            set { m_RegularExpressionErrorMessage = value; }
        }
        public string RegularExpression
        {
            get { return m_RegularExpression; }
            set { m_RegularExpression = value; }
        }
        #endregion
        #region Methods
        private string GetControlValue(Control control)
        {
            string _Value = "";
            if (control is ComboBox || control is DevComponents.DotNetBar.Controls.ComboBoxEx)
            {
                if (((ComboBox)control).SelectedItem != null)
                    _Value = ((ListBoxItem)((ComboBox)control).SelectedItem).Value;
                else
                    _Value = "0";
            }
            else if (control is TextBox || control is DevComponents.DotNetBar.Controls.TextBoxX)
                _Value = ((TextBox)control).Text;
            return _Value;
        }
        public void Validate()
        {
            try
            {
                m_IsValid = true;
                if (this.Enabled)
                {
                    string _ControlValue = GetControlValue(m_ControlToValidate);
                    if (m_RequiredFieldValidator && m_IsValid)
                    {
                        m_IsValid = _ControlValue != m_InitialValue;
                        if (!m_IsValid)
                            this.Text = m_RequiredFieldErrorMessage;
                    }
                    if (m_CompareValidator && m_IsValid) //Don't validate this if the last one failed
                    {
                        if (!String.IsNullOrEmpty(_ControlValue))
                        {
                            string _CompareValue = !String.IsNullOrEmpty(m_ValueToCompare) ? m_ValueToCompare : GetControlValue(m_ControlToCompare);
                            switch (m_DataType)
                            {
                                case ValidationDataTypes.Integer:
                                    if (ConvertHelper.ToInt32(_ControlValue) == Int32.MinValue || (!String.IsNullOrEmpty(_CompareValue) && ConvertHelper.Todouble(_CompareValue) == Int32.MinValue))
                                        m_IsValid = false;
                                    break;
                                case ValidationDataTypes.Double:
                                    if (ConvertHelper.Todouble(_ControlValue) == double.MinValue || (!String.IsNullOrEmpty(_CompareValue) && ConvertHelper.Todouble(_CompareValue) == double.MinValue))
                                        m_IsValid = false;
                                    break;
                            }
                            if (m_IsValid)
                            {
                                switch (m_DataType)
                                {
                                    case ValidationDataTypes.String:
                                        switch (m_Operator)
                                        {
                                            case ValidationOperators.Equal:
                                                m_IsValid = _ControlValue == _CompareValue;
                                                break;
                                            case ValidationOperators.Different:
                                                m_IsValid = _ControlValue != _CompareValue;
                                                break;
                                            case ValidationOperators.LowerThan:
                                                m_IsValid = false;
                                                break;
                                            case ValidationOperators.GraterThan:
                                                m_IsValid = false;
                                                break;
                                            case ValidationOperators.LowerThanEqual:
                                                m_IsValid = false;
                                                break;
                                            case ValidationOperators.GreaterThanEqual:
                                                m_IsValid = false;
                                                break;
                                        }
                                        break;
                                    case ValidationDataTypes.Integer:
                                        switch (m_Operator)
                                        {
                                            case ValidationOperators.Equal:
                                                m_IsValid = ConvertHelper.ToInt32(_ControlValue) == ConvertHelper.ToInt32(_CompareValue);
                                                break;
                                            case ValidationOperators.Different:
                                                m_IsValid = ConvertHelper.ToInt32(_ControlValue) != ConvertHelper.ToInt32(_CompareValue);
                                                break;
                                            case ValidationOperators.LowerThan:
                                                m_IsValid = ConvertHelper.ToInt32(_ControlValue) < ConvertHelper.ToInt32(_CompareValue);
                                                break;
                                            case ValidationOperators.GraterThan:
                                                m_IsValid = ConvertHelper.ToInt32(_ControlValue) > ConvertHelper.ToInt32(_CompareValue);
                                                break;
                                            case ValidationOperators.LowerThanEqual:
                                                m_IsValid = ConvertHelper.ToInt32(_ControlValue) <= ConvertHelper.ToInt32(_CompareValue);
                                                break;
                                            case ValidationOperators.GreaterThanEqual:
                                                m_IsValid = ConvertHelper.ToInt32(_ControlValue) >= ConvertHelper.ToInt32(_CompareValue);
                                                break;
                                        }
                                        break;
                                    case ValidationDataTypes.Double:
                                        switch (m_Operator)
                                        {
                                            case ValidationOperators.Equal:
                                                m_IsValid = ConvertHelper.Todouble(_ControlValue) == ConvertHelper.Todouble(_CompareValue);
                                                break;
                                            case ValidationOperators.Different:
                                                m_IsValid = ConvertHelper.Todouble(_ControlValue) != ConvertHelper.Todouble(_CompareValue);
                                                break;
                                            case ValidationOperators.LowerThan:
                                                m_IsValid = ConvertHelper.Todouble(_ControlValue) < ConvertHelper.Todouble(_CompareValue);
                                                break;
                                            case ValidationOperators.GraterThan:
                                                m_IsValid = ConvertHelper.Todouble(_ControlValue) > ConvertHelper.Todouble(_CompareValue);
                                                break;
                                            case ValidationOperators.LowerThanEqual:
                                                m_IsValid = ConvertHelper.Todouble(_ControlValue) <= ConvertHelper.Todouble(_CompareValue);
                                                break;
                                            case ValidationOperators.GreaterThanEqual:
                                                m_IsValid = ConvertHelper.Todouble(_ControlValue) >= ConvertHelper.Todouble(_CompareValue);
                                                break;
                                        }
                                        break;
                                }
                            }
                            else
                                m_IsValid = false;
                            if (!m_IsValid)
                                this.Text = m_CompareErrorMessage;
                        }
                    }
                    if (m_RegularExpressionValidator && m_IsValid) //Don't validate this if the last one failed
                    {
                        m_IsValid = Regex.IsMatch(_ControlValue, m_RegularExpression);
                        if (!m_IsValid)
                            this.Text = m_RegularExpressionErrorMessage;
                    }
                    this.Visible = !m_IsValid;
                }
            }
            catch(Exception ex)
            {
            }
        }
        #endregion
    }
}
